COSC 220 Computer Science II

 

Debugging Strategies and Debugging with gdb and valgrind


This demo will give you some practical experience with debugging using gdb. Before you start the following tasks, go to the following link and read over the following tutorial material:

Tasks

  1. Do the DebugMe (debugme.c) Code
    1. Compile using 'gcc -g -o debugme debugme.c'
    2. Run the executable by typing 'debugme "hi there" "bye bye"'
    3. Debug the executable
      1. Type 'gdb debugme'
      2. Read the source code by typing 'list 1' (list 10 lines starting at line 1). To read 10 more lines, just type 'list'
      3. Run the program by typing 'run "hi there" "bye bye"' It should run successfully.
      4. Read the source code and find the line that calls the function print_string (around line 33). Determine the line number and set a breakpoint there by typing 'break 33' (or whatever the line number was).
      5. Step through the loop using 'next'. Each time through, examine the values of i and argv[i] by typing 'print i' and 'print argv[i]'
      6. Get information about the breakpoints by typing 'info break'. Remember the breakpoint's number.
      7. Delete the breakpoint by typing 'delete n' where n is the breakpoint's number, then finish off the program by typing 'continue'
      8. Remake the breakpoint, then run the program as before. It will stop at the call to print_string. This time, we'll step into the function. Type 'step' and observe that you are inside the function.
      9. Print the values of num and string; you should see their current values.
      10. Try to print the values of i and argv. They should not be defined in the current context since they are local to main.

  2. Do the CrashMe  (arrayTest.cpp) Code. This program has a serious run-time bug; the array bounds are easy to violate.
    1. Compile arrayTest.cpp using g++. Make sure the debug flag is set.
    2. Run the executable, entering various values for the index. Keep increasing the value until a run-time fault occurs.
    3. Now run the executable in the debugger. You should get the run-time error along with an indication of where it occurred.

  3. Do the Factorial (factorial.h, factorial.cpp, facDemo.cpp) Code. This will allow you to trace the call stack during debugging.
    1. Compile factDemo.cpp and factorial.cpp into an executable named fact.
    2. Start gdb on the executable.
    3. Put a breakpoint in main on the call to factorial (around line 23).
    4. Run the program. When it stops at the breakpoint, step into the factorial function.
    5. 'next' through the base cases, then 'step' into the recursive call. Do this a few times.
    6. Now, take a look at the function call stack by typing 'backtrace' Note the stack of recursive calls, each with a different value of the parameter n.
    7. Now, we'll mess with the program by changing the value of a variable. Run the program again by typing 'run'. Step into main's call to factorial.
    8. Inside the factorial function, print the value of n. Now change the value of n by typing 'set  variable n=5' (any value as long as it's different from the current value of n).
    9. Delete the breakpoint and allow the program to complete by typing 'continue' .
    10. The value printed for n! should be for the changed value of n.